
const arr = new Array(9999999).fill(0)
console.time('FOR1~~')
for(let i = 0; i < arr.length; i++){}
console.timeEnd('FOR1~~') //  11ms

let i = 0;
console.time('WHILE1~~')
while(i < arr.length){
    i++
}
console.timeEnd('WHILE1~~') // 20ms

console.time('FOR2~~')
for(var j = 0; j < arr.length; j++){}
console.timeEnd('FOR2~~') // 15ms

var j = 0;
console.time('WHILE2~~')
while(j < arr.length){
    j++
}
console.timeEnd('WHILE2~~') // 15ms

console.time('FOREACH~~')
arr.forEach(()=>{})
console.timeEnd('FOREACH~~') // 87ms

console.time('FORIN~~')
for(let i in arr){} // i 是序列号(index值), for in 会遍历当前对象可枚举属性 跟 当前对象上原型链上的所有可枚举的属性，所以性能很低。
console.timeEnd('FORIN~~') // 2719ms

/**
 * 扩展:
 * for in时，可用obj.hasOwnPrototype(prop)来判断属性是否是当前对象上的属性。
 * Object.keys(obj) 只获取当前对象上的可枚举属性，不会拿原型链上的
 * Object.getOwnPropertySymbols(obj) 可获取当前对象上的 Symbol 属性
 * 
    let obj = {
        name:'zj',
        age:29,
        [Symbol('sec')]:'不能说'
    }
    for(let k in obj){}
    Object.keys(obj)
    Object.getOwnPropertySymbols(obj)
 */

console.time('FOROF~~')
for(let val of arr){} // 调用的其实是迭代器方法,这里会调用到arr.__proto__上面的[Symbol.iterator]方法，val是各项数组的值
console.timeEnd('FOROF~~') // 127ms
/**
 * 扩展：迭代器
 * 迭代器方法就是一个函数，里面返回一个对象包含next方法，
 * next方法里返回一个对象 { done: false Or true, value: xxx }
 */

// 重写arr的Symbol.iterator方法
const arr2 = [10,20,30,40,50]
arr2[Symbol.iterator] = function(){
    let self = this;
    let index = 0;
    return {
        next(){
            if(index > self.length - 1){
                return {
                    done:true,
                    value: undefined
                }
            }
            // index += 2 // 这样就只取 index为偶数的项（没有第0项）
            return {
                done: false,
                // value: self[index]
                value: self[index++]
            }
        }
    }
}

for(let val of arr2){
    console.log(val)
}

